home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2001 May / may_2001.iso / intercd / root / Multimedia / ^DivX_Article / virtualdub / VirtualDub-source-1_4d / a_convertout.asm < prev    next >
Encoding:
Assembly Source File  |  2001-03-20  |  26.4 KB  |  1,639 lines

  1. ;    VirtualDub - Video processing and capture application
  2. ;    Copyright (C) 1998-2001 Avery Lee
  3. ;
  4. ;    This program is free software; you can redistribute it and/or modify
  5. ;    it under the terms of the GNU General Public License as published by
  6. ;    the Free Software Foundation; either version 2 of the License, or
  7. ;    (at your option) any later version.
  8. ;
  9. ;    This program is distributed in the hope that it will be useful,
  10. ;    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. ;    GNU General Public License for more details.
  13. ;
  14. ;    You should have received a copy of the GNU General Public License
  15. ;    along with this program; if not, write to the Free Software
  16. ;    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18.     .586
  19.     .mmx
  20.     .model    flat
  21.  
  22.     extern _MMX_enabled : byte
  23.  
  24.     public    _DIBconvert_32_to_16
  25.     public    _DIBconvert_32_to_16_dithered
  26.     public    _DIBconvert_32_to_16_565
  27.     public    _DIBconvert_32_to_16_565_dithered
  28.     public    _DIBconvert_32_to_24
  29.     public    _DIBconvert_32_to_32
  30.  
  31.     .code
  32.  
  33. ;***************************************************
  34.  
  35. ; void DIBconvert_32_to_32(
  36. ;    void *dest,        [ESP+ 4]
  37. ;    ulong dest_pitch,    [ESP+ 8]
  38. ;    void *src,        [ESP+12]
  39. ;    ulong src_pitch,    [ESP+16]
  40. ;    ulong width,        [ESP+20]
  41. ;    ulong height);        [ESP+24]
  42. ;
  43. ;    this isn't THAT stupid a function!!
  44.  
  45. _DIBconvert_32_to_32:
  46.     push    edi
  47.     push    esi
  48.     push    edx
  49.     push    ecx
  50.     push    ebx
  51.     push    eax
  52.  
  53.     mov    edx,[esp+24+24]
  54.  
  55.     mov    eax,[esp+20+24]
  56.     mov    esi,[esp+12+24]
  57.     mov    edi,[esp+ 4+24]
  58.  
  59. DIBconvert3232@y:
  60.     push    esi
  61.     push    edi
  62.     mov    ecx,eax
  63.     rep    movsd
  64.     pop    edi
  65.     pop    esi
  66.     add    esi,[esp+16+24]
  67.     add    edi,[esp+ 8+24]
  68.  
  69.     dec    edx
  70.     jne    DIBconvert3232@y
  71.  
  72.     pop    eax
  73.     pop    ebx
  74.     pop    ecx
  75.     pop    edx
  76.     pop    esi
  77.     pop    edi
  78.  
  79.     ret
  80.  
  81. ; void DIBconvert_32_to_24(
  82. ;    void *dest,        [ESP+ 4]
  83. ;    ulong dest_pitch,    [ESP+ 8]
  84. ;    void *src,        [ESP+12]
  85. ;    ulong src_pitch,    [ESP+16]
  86. ;    ulong width,        [ESP+20]
  87. ;    ulong height);        [ESP+24]
  88.  
  89. _DIBconvert_32_to_24:
  90.     push    ebp
  91.     push    edi
  92.     push    esi
  93.     push    edx
  94.     push    ecx
  95.     push    ebx
  96.     push    eax
  97.  
  98.     mov    esi,[esp+12+28]
  99.     mov    edi,[esp+4+28]
  100.  
  101.     mov    ecx,[esp+20+28]
  102.     lea    eax,[ecx+ecx*2]
  103.     lea    ebx,[ecx*4]
  104.     sub    [esp+8+28],eax
  105.     sub    [esp+16+28],ebx
  106.  
  107.     mov    edx,[esp+24+28]
  108. DIBconvert3224@y:
  109.     mov    ecx,[esp+20+28]
  110.     push    ecx
  111.     push    edx
  112.     shr    ecx,2
  113.     jz    DIBconvert3224@x2
  114. DIBconvert3224@x:
  115.     mov    eax,[esi]        ;EAX = xxr0g0b0
  116.     mov    ebx,[esi+4]        ;EBX = xxr1g1b1
  117.     mov    edx,ebx            ;EDX = xxr1g1b1
  118.     mov    ebp,[esi+8]        ;EBP = xxr2g2b2
  119.     shl    ebx,24            ;EBX = b1000000
  120.     and    eax,00ffffffh        ;EAX = 00r0g0b0
  121.     shr    edx,8            ;EDX = 00xxr1g1
  122.     or    eax,ebx            ;EAX = b1r0g0b0
  123.     mov    [edi+0],eax
  124.     mov    ebx,ebp            ;EBX = xxr2g2b2
  125.     shl    ebp,16            ;EBP = g2b20000
  126.     and    edx,0000ffffh        ;EDX = 0000r1g1
  127.     or    ebp,edx            ;EBP = g2b2r1g1
  128.     mov    eax,[esi+12]        ;EAX = xxr3g3b3
  129.     shr    ebx,16            ;EBX = 0000xxr2
  130.     add    edi,12
  131.     shl    eax,8            ;EAX = r3g3b300
  132.     and    ebx,000000ffh        ;EBX = 000000r2
  133.     or    eax,ebx            ;EAX = r3g3b3r2
  134.     mov    [edi+4-12],ebp
  135.     add    esi,16
  136.     mov    [edi+8-12],eax
  137.     dec    ecx
  138.     jne    DIBconvert3224@x
  139. DIBconvert3224@x2:
  140.     pop    edx
  141.     pop    ecx
  142.     and    ecx,3
  143.     jz    DIBconvert3224@x3
  144. DIBconvert3224@x4:
  145.     mov    eax,[esi]
  146.     add    esi,4
  147.     mov    [edi],ax
  148.     shr    eax,16
  149.     mov    [edi+2],al
  150.     add    edi,3
  151.     dec    ecx
  152.     jnz    DIBconvert3224@x4
  153. DIBconvert3224@x3:
  154.  
  155.     add    esi,[esp+16+28]
  156.     add    edi,[esp+ 8+28]
  157.  
  158.     dec    edx
  159.     jne    DIBconvert3224@y
  160.  
  161.     pop    eax
  162.     pop    ebx
  163.     pop    ecx
  164.     pop    edx
  165.     pop    esi
  166.     pop    edi
  167.     pop    ebp
  168.  
  169.     ret
  170.  
  171. ;******************************************************
  172. ;
  173. ; void DIBconvert_32_to_16(
  174. ;    void *dest,        [ESP+ 4]
  175. ;    ulong dest_pitch,    [ESP+ 8]
  176. ;    void *src,        [ESP+12]
  177. ;    ulong src_pitch,    [ESP+16]
  178. ;    ulong width,        [ESP+20]
  179. ;    ulong height);        [ESP+24]
  180.  
  181. _DIBconvert_32_to_16:
  182.     test    _MMX_enabled,1
  183.     jnz    _DIBconvert_32_to_16MMX
  184.  
  185.  
  186.     push    ebp
  187.     push    edi
  188.     push    esi
  189.     push    edx
  190.     push    ecx
  191.     push    ebx
  192.     push    eax
  193.  
  194.     mov    esi,[esp+12+28]
  195.     mov    edi,[esp+4+28]
  196.  
  197.     mov    ebp,[esp+20+28]
  198.     lea    eax,[ebp+ebp]
  199.     lea    ebx,[ebp*4]
  200.     sub    [esp+8+28],eax
  201.     sub    [esp+16+28],ebx
  202.  
  203.     mov    edx,[esp+24+28]
  204. DIBconvert3216@y:
  205.     mov    ebp,[esp+20+28]
  206.     push    ebp
  207.     push    edx
  208.     shr    ebp,1
  209.     jz    DIBconvert3216@x2
  210. DIBconvert3216@x:
  211.     mov    eax,[esi+4]        ;u
  212.     add    esi,8            ;v
  213.  
  214.     mov    ebx,eax            ;u
  215.     mov    ecx,eax            ;v
  216.     shr    ebx,3            ;u
  217.     and    ecx,0000f800h        ;v
  218.     shr    eax,9            ;u
  219.     and    ebx,0000001fh        ;v
  220.     shr    ecx,6            ;u
  221.     and    eax,00007c00h        ;v
  222.     or    ebx,ecx            ;u
  223.     add    edi,4            ;v
  224.     or    ebx,eax            ;u
  225.  
  226.     mov    ecx,[esi-8]        ;v
  227.     mov    edx,ebx            ;u
  228.     mov    eax,ecx            ;v
  229.  
  230.     shl    edx,16            ;u
  231.     mov    ebx,ecx            ;v
  232.     shr    ebx,3            ;u
  233.     and    ecx,0000f800h        ;v
  234.     shr    eax,9            ;u
  235.     and    ebx,0000001fh        ;v
  236.     shr    ecx,6            ;u
  237.     and    eax,00007c00h        ;v
  238.     or    eax,ecx            ;u
  239.     or    edx,ebx            ;v
  240.     or    edx,eax            ;u
  241.     dec    ebp            ;v
  242.     mov    [edi-4],edx        ;u
  243.     jne    DIBconvert3216@x    ;v
  244. DIBconvert3216@x2:
  245.     pop    edx
  246.     pop    ebp
  247.     and    ebp,1
  248.     jz    DIBconvert3216@x3
  249.     mov    eax,[esi]
  250.     add    esi,4
  251.  
  252.     mov    ebx,eax
  253.     mov    ecx,eax
  254.     shr    ebx,3
  255.     and    ecx,0000f800h
  256.     shr    eax,9
  257.     and    ebx,0000001fh
  258.     shr    ecx,6
  259.     and    eax,00007c00h
  260.     or    ebx,ecx
  261.     or    ebx,eax
  262.     mov    [edi+0],bl
  263.     mov    [edi+1],bh
  264.     add    edi,2
  265. DIBconvert3216@x3:
  266.  
  267.     add    esi,[esp+16+28]
  268.     add    edi,[esp+ 8+28]
  269.  
  270.     dec    edx
  271.     jne    DIBconvert3216@y
  272.  
  273.     pop    eax
  274.     pop    ebx
  275.     pop    ecx
  276.     pop    edx
  277.     pop    esi
  278.     pop    edi
  279.     pop    ebp
  280.  
  281.     ret
  282.  
  283. ;******************************************************
  284. ;
  285. ; void DIBconvert_32_to_16_565(
  286. ;    void *dest,        [ESP+ 4]
  287. ;    ulong dest_pitch,    [ESP+ 8]
  288. ;    void *src,        [ESP+12]
  289. ;    ulong src_pitch,    [ESP+16]
  290. ;    ulong width,        [ESP+20]
  291. ;    ulong height);        [ESP+24]
  292.  
  293. _DIBconvert_32_to_16_565:
  294.     test    _MMX_enabled,1
  295.     jnz    _DIBconvert_32_to_16_565MMX
  296.  
  297.  
  298.     push    ebp
  299.     push    edi
  300.     push    esi
  301.     push    edx
  302.     push    ecx
  303.     push    ebx
  304.     push    eax
  305.  
  306.     mov    esi,[esp+12+28]
  307.     mov    edi,[esp+4+28]
  308.  
  309.     mov    ebp,[esp+20+28]
  310.     lea    eax,[ebp+ebp]
  311.     lea    ebx,[ebp*4]
  312.     sub    [esp+8+28],eax
  313.     sub    [esp+16+28],ebx
  314.  
  315.     mov    edx,[esp+24+28]
  316. DIBconvert3216565@y:
  317.     mov    ebp,[esp+20+28]
  318.     push    ebp
  319.     push    edx
  320.     shr    ebp,1
  321.     jz    DIBconvert3216565@x2
  322. DIBconvert3216565@x:
  323.     mov    eax,[esi+4]        ;u
  324.     add    esi,8            ;v
  325.  
  326.     mov    ebx,eax            ;u
  327.     mov    ecx,eax            ;v
  328.     shr    ebx,3            ;u
  329.     and    ecx,0000fc00h        ;v
  330.     shr    eax,8            ;u
  331.     and    ebx,0000001fh        ;v
  332.     shr    ecx,5            ;u
  333.     and    eax,0000f800h        ;v
  334.     or    ebx,ecx            ;u
  335.     add    edi,4            ;v
  336.     or    ebx,eax            ;u
  337.  
  338.     mov    ecx,[esi-8]        ;v
  339.     mov    edx,ebx            ;u
  340.     mov    eax,ecx            ;v
  341.  
  342.     shl    edx,16            ;u
  343.     mov    ebx,ecx            ;v
  344.     shr    ebx,3            ;u
  345.     and    ecx,0000fc00h        ;v
  346.     shr    eax,8            ;u
  347.     and    ebx,0000001fh        ;v
  348.     shr    ecx,5            ;u
  349.     and    eax,0000f800h        ;v
  350.     or    eax,ecx            ;u
  351.     or    edx,ebx            ;v
  352.     or    edx,eax            ;u
  353.     dec    ebp            ;v
  354.     mov    [edi-4],edx        ;u
  355.     jne    DIBconvert3216565@x    ;v
  356. DIBconvert3216565@x2:
  357.     pop    edx
  358.     pop    ebp
  359.     and    ebp,1
  360.     jz    DIBconvert3216565@x3
  361.     mov    eax,[esi]
  362.     add    esi,4
  363.  
  364.     mov    ebx,eax
  365.     mov    ecx,eax
  366.     shr    ebx,3
  367.     and    ecx,0000fc00h
  368.     shr    eax,8
  369.     and    ebx,0000001fh
  370.     shr    ecx,5
  371.     and    eax,0000f800h
  372.     or    ebx,ecx
  373.     or    ebx,eax
  374.     mov    [edi+0],bl
  375.     mov    [edi+1],bh
  376.     add    edi,2
  377. DIBconvert3216565@x3:
  378.  
  379.     add    esi,[esp+16+28]
  380.     add    edi,[esp+ 8+28]
  381.  
  382.     dec    edx
  383.     jne    DIBconvert3216565@y
  384.  
  385.     pop    eax
  386.     pop    ebx
  387.     pop    ecx
  388.     pop    edx
  389.     pop    esi
  390.     pop    edi
  391.     pop    ebp
  392.  
  393.     ret
  394.  
  395. ;***********************************************************************************
  396.  
  397.     .const
  398.     align    8
  399.  
  400. DIBconvert3216MMX@red_blue_mask        dq    00f800f800f800f8h
  401. DIBconvert3216MMX@green_mask        dq    0000f8000000f800h
  402. DIBconvert3216MMX@red_blue_mult        dq    2000000820000008h
  403. DIBconvert3216MMX@565_green_mask    dq    0000fc000000f800h
  404. DIBconvert3216MMX@565_red_blue_mult    dq    2000000420000004h
  405.  
  406.     .code
  407.  
  408.     align    16
  409. _DIBconvert_32_to_16MMX:
  410.     push    ebp
  411.     push    edi
  412.     push    esi
  413.     push    edx
  414.     push    ecx
  415.     push    ebx
  416.     push    eax
  417.  
  418.     mov    esi,[esp+12+28]
  419.     mov    edi,[esp+4+28]
  420.  
  421.     mov    ebp,[esp+20+28]
  422.     lea    eax,[ebp+ebp]
  423.     lea    ebx,[ebp*4]
  424.     sub    [esp+8+28],eax
  425.     sub    [esp+16+28],ebx
  426.  
  427.     mov    edx,[esp+24+28]
  428. DIBconvert3216MMX@y:
  429.     mov    ebp,[esp+20+28]
  430.     push    ebp
  431.     push    edx
  432.     shr    ebp,3
  433.     jz    DIBconvert3216MMX@x2
  434.     shl    ebp,4
  435.  
  436.     movq        mm5,DIBconvert3216MMX@red_blue_mult
  437.     movq        mm6,DIBconvert3216MMX@red_blue_mask
  438.     movq        mm7,DIBconvert3216MMX@green_mask
  439.  
  440.     movq        mm0,[esi+ebp*2-32]    ;allocate 0    (01234)
  441.     movq        mm2,mm0            ;allocate 2    (0 234)
  442.  
  443.     movq        mm1,[esi+ebp*2-24]    ;allocate 1    (01234)
  444.     movq        mm3,mm1            ;allocate 3    (01234)
  445.     pand        mm0,mm6
  446.     pmaddwd        mm0,mm5
  447.     pand        mm1,mm6
  448.     pmaddwd        mm1,mm5
  449.     pand        mm2,mm7
  450.     pand        mm3,mm7
  451.     jmp        short DIBconvert3216MMX@loopstart
  452.  
  453.     align 16
  454. DIBconvert3216MMX@x:
  455.  
  456. ;*******************************
  457.  
  458.     movq        mm0,[esi+ebp*2-32]    ;allocate 0    (01234)
  459.     por        mm4,mm2            ;free 2        (01 34)
  460.  
  461.     por        mm3,mm1            ;free 3        (01 34)
  462.     psrlq        mm4,6
  463.  
  464.     psrlq        mm3,6
  465.     movq        mm2,mm0            ;allocate 2    (0 234)
  466.  
  467.     movq        mm1,[esi+ebp*2-24]    ;allocate 1    (01234)
  468.     packssdw    mm4,mm3            ;free 3        (012 4)
  469.  
  470.     movq        mm3,mm1            ;allocate 3    (01234)
  471.     pand        mm0,mm6
  472.  
  473.     pmaddwd        mm0,mm5
  474.     pand        mm1,mm6
  475.  
  476.     pmaddwd        mm1,mm5
  477.     pand        mm2,mm7
  478.  
  479.     movq        [edi+ebp+8],mm4        ;free 4        (0123 )
  480.     pand        mm3,mm7
  481.  
  482. DIBconvert3216MMX@loopstart:
  483.     movq        mm4,[esi+ebp*2-16]    ;allocate 4    (01234)
  484.     por        mm0,mm2            ;free 2        (01 34)
  485.  
  486.     por        mm1,mm3            ;free 3        (01  4)
  487.     psrlq        mm0,6
  488.  
  489.     movq        mm3,[esi+ebp*2-8]    ;allocate 3    (01 34)
  490.     psrlq        mm1,6
  491.  
  492.     movq        mm2,mm4            ;allocate 2    (01234)
  493.     packssdw    mm0,mm1            ;free 1        (0 234)
  494.  
  495.     movq        mm1,mm3            ;allocate 1    (01234)
  496.     pand        mm4,mm6
  497.  
  498.     movq        [edi+ebp-16],mm0    ;free 0        ( 1234)
  499.     pand        mm3,mm6
  500.  
  501.     pmaddwd        mm4,mm5
  502.     pand        mm2,mm7
  503.  
  504.     pmaddwd        mm3,mm5
  505.     pand        mm1,mm7
  506.  
  507.     sub        ebp,16
  508.     jne        DIBconvert3216MMX@x
  509.  
  510.     ;--------------
  511.  
  512.     por        mm4,mm2            ;free 2        (01 34)
  513.     por        mm3,mm1            ;free 3        (01 34)
  514.     psrlq        mm4,6
  515.     psrlq        mm3,6
  516.     packssdw    mm4,mm3            ;free 3        (012 4)
  517.     movq        [edi+8],mm4        ;free 4        (0123 )
  518.  
  519. ;*******************************
  520.  
  521. DIBconvert3216MMX@x2:
  522.     pop    edx
  523.     pop    ebp
  524.  
  525.     mov    eax,ebp
  526.     and    eax,0fffffff8h
  527.     add    eax,eax
  528.     add    edi,eax
  529.     add    eax,eax
  530.     add    esi,eax
  531.     push    ebp
  532.  
  533.     and    ebp,6
  534.     jz    DIBconvert3216MMX@x4
  535.  
  536. DIBconvert3216MMX@x5:
  537.     movq        mm0,[esi]
  538.     add        esi,8
  539.     movq        mm1,mm0
  540.     pand        mm0,DIBconvert3216MMX@red_blue_mask
  541.     pand        mm1,DIBconvert3216MMX@green_mask
  542.     pmaddwd        mm0,DIBconvert3216MMX@red_blue_mult
  543.     paddw        mm0,mm1
  544.     psrld        mm0,6
  545.     packssdw    mm0,mm0
  546.     movd        [edi],mm0
  547.     add        edi,4
  548.     sub    ebp,2
  549.     jne    DIBconvert3216MMX@x5
  550.  
  551. DIBconvert3216MMX@x4:
  552.     pop    ebp
  553.  
  554.     and    ebp,1
  555.     jz    DIBconvert3216MMX@x3
  556.     mov    eax,[esi]
  557.     add    esi,4
  558.  
  559.     mov    ebx,eax
  560.     mov    ecx,eax
  561.     shr    ebx,3
  562.     and    ecx,0000f800h
  563.     shr    eax,9
  564.     and    ebx,0000001fh
  565.     shr    ecx,6
  566.     and    eax,00007c00h
  567.     or    ebx,ecx
  568.     add    edi,2
  569.     or    ebx,eax
  570.     mov    [edi+0],bl
  571.     mov    [edi+1],bh
  572. DIBconvert3216MMX@x3:
  573.  
  574.     add    esi,[esp+16+28]
  575.     add    edi,[esp+ 8+28]
  576.  
  577.     dec    edx
  578.     jne    DIBconvert3216MMX@y
  579.  
  580.     pop    eax
  581.     pop    ebx
  582.     pop    ecx
  583.     pop    edx
  584.     pop    esi
  585.     pop    edi
  586.     pop    ebp
  587.     emms
  588.  
  589.     ret
  590.  
  591.  
  592.  
  593. _DIBconvert_32_to_16_565MMX:
  594.     push    ebp
  595.     push    edi
  596.     push    esi
  597.     push    edx
  598.     push    ecx
  599.     push    ebx
  600.     push    eax
  601.  
  602.     mov    esi,[esp+12+28]
  603.     mov    edi,[esp+4+28]
  604.  
  605.     mov    ebp,[esp+20+28]
  606.     lea    eax,[ebp+ebp]
  607.     lea    ebx,[ebp*4]
  608.     sub    [esp+8+28],eax
  609.     sub    [esp+16+28],ebx
  610.  
  611.     mov    edx,[esp+24+28]
  612. DIBconvert3216565MMX@y:
  613.     mov    ebp,[esp+20+28]
  614.     push    ebp
  615.     push    edx
  616.     shr    ebp,3
  617.     jz    DIBconvert3216565MMX@x2
  618.     shl    ebp,4
  619.  
  620.     movq        mm5,DIBconvert3216MMX@565_red_blue_mult
  621.     movq        mm6,DIBconvert3216MMX@red_blue_mask
  622.     movq        mm7,DIBconvert3216MMX@565_green_mask
  623.  
  624.     movq        mm0,[esi+ebp*2-32]    ;allocate 0    (0123)
  625.     movq        mm2,mm0            ;allocate 2    (0 23)
  626.  
  627.     movq        mm1,[esi+ebp*2-24]    ;allocate 1    (0123)
  628.     movq        mm3,mm1            ;allocate 3    (0123)
  629.     pand        mm0,mm6
  630.     pmaddwd        mm0,mm5
  631.     pand        mm1,mm6
  632.     pmaddwd        mm1,mm5
  633.     pand        mm2,mm7
  634.     pand        mm3,mm7
  635.     jmp        short DIBconvert3216565MMX@loopstart
  636.  
  637.     align 16
  638.  
  639. DIBconvert3216565MMX@x:
  640.  
  641. ;*******************************
  642.  
  643.     movq        mm0,[esi+ebp*2-32]    ;allocate 0    (01234)
  644.     por        mm4,mm2            ;free 2        (01 34)
  645.  
  646.     por        mm3,mm1            ;free 3        (01 34)
  647.     pslld        mm4,16-5
  648.  
  649.     pslld        mm3,16-5
  650.     movq        mm2,mm0            ;allocate 2    (0 234)
  651.  
  652.     movq        mm1,[esi+ebp*2-24]    ;allocate 1    (01234)
  653.     psrad        mm4,16
  654.  
  655.     psrad        mm3,16
  656.     pand        mm0,mm6
  657.  
  658.     packssdw    mm4,mm3            ;free 3        (012 4)
  659.     movq        mm3,mm1            ;allocate 3    (01234)
  660.  
  661.     pmaddwd        mm0,mm5
  662.     pand        mm1,mm6
  663.  
  664.     pmaddwd        mm1,mm5
  665.     pand        mm2,mm7
  666.  
  667.     movq        [edi+ebp+8],mm4        ;free 4        (0123 )
  668.     pand        mm3,mm7
  669.  
  670. DIBconvert3216565MMX@loopstart:
  671.     movq        mm4,[esi+ebp*2-16]    ;allocate 4    (01234)
  672.     por        mm0,mm2            ;free 2        (01 34)
  673.  
  674.     por        mm1,mm3            ;free 3        (01  4)
  675.     pslld        mm0,16-5
  676.  
  677.     movq        mm3,[esi+ebp*2-8]    ;allocate 3    (01 34)
  678.     pslld        mm1,16-5
  679.  
  680.     psrad        mm0,16
  681.     movq        mm2,mm4            ;allocate 2    (01234)
  682.  
  683.     psrad        mm1,16
  684.     pand        mm4,mm6
  685.  
  686.     packssdw    mm0,mm1            ;free 1        (0 234)
  687.     movq        mm1,mm3            ;allocate 1    (01234)
  688.  
  689.     movq        [edi+ebp-16],mm0    ;free 0        ( 1234)
  690.     pand        mm3,mm6
  691.  
  692.     pmaddwd        mm4,mm5
  693.     sub        ebp,16
  694.  
  695.     pmaddwd        mm3,mm5
  696.     pand        mm2,mm7
  697.  
  698.     pand        mm1,mm7
  699.     jne        DIBconvert3216565MMX@x
  700.  
  701.     ;--------------
  702.  
  703.     por        mm4,mm2            ;free 2        (01 34)
  704.     por        mm3,mm1            ;free 3        (01 34)
  705.     psllq        mm4,16-5
  706.     psllq        mm3,16-5
  707.     psrad        mm4,16
  708.     psrad        mm3,16
  709.     packssdw    mm4,mm3            ;free 3        (012 4)
  710.     movq        [edi+8],mm4        ;free 4        (0123 )
  711.  
  712.  
  713. ;*******************************
  714.  
  715. DIBconvert3216565MMX@x2:
  716.     pop    edx
  717.     pop    ebp
  718.  
  719.     mov    eax,ebp
  720.     and    eax,0fffffff8h
  721.     add    eax,eax
  722.     add    edi,eax
  723.     add    eax,eax
  724.     add    esi,eax
  725.     push    ebp
  726.  
  727.     and    ebp,6
  728.     jz    DIBconvert3216565MMX@x4
  729.  
  730. DIBconvert3216565MMX@x5:
  731.     movq        mm0,[esi]
  732.     add        esi,8
  733.     movq        mm1,mm0
  734.     pand        mm0,DIBconvert3216MMX@red_blue_mask
  735.     pand        mm1,DIBconvert3216MMX@565_green_mask
  736.     pmaddwd        mm0,DIBconvert3216MMX@565_red_blue_mult
  737.     paddw        mm0,mm1
  738.     pslld        mm0,16-5
  739.     psrad        mm0,16
  740.     packssdw    mm0,mm0
  741.     movd        [edi],mm0
  742.     add        edi,4
  743.     sub    ebp,2
  744.     jne    DIBconvert3216565MMX@x5
  745.  
  746. DIBconvert3216565MMX@x4:
  747.     pop    ebp
  748.  
  749.     and    ebp,1
  750.     jz    DIBconvert3216565MMX@x3
  751.     mov    eax,[esi]
  752.     add    esi,4
  753.  
  754.     mov    ebx,eax
  755.     mov    ecx,eax
  756.     shr    ebx,3
  757.     and    ecx,0000fc00h
  758.     shr    eax,8
  759.     and    ebx,0000001fh
  760.     shr    ecx,5
  761.     and    eax,0000f800h
  762.     or    ebx,ecx
  763.     add    edi,2
  764.     or    ebx,eax
  765.     mov    [edi+0],bl
  766.     mov    [edi+1],bh
  767. DIBconvert3216565MMX@x3:
  768.  
  769.     add    esi,[esp+16+28]
  770.     add    edi,[esp+ 8+28]
  771.  
  772.     dec    edx
  773.     jne    DIBconvert3216565MMX@y
  774.  
  775.     pop    eax
  776.     pop    ebx
  777.     pop    ecx
  778.     pop    edx
  779.     pop    esi
  780.     pop    edi
  781.     pop    ebp
  782.     emms
  783.  
  784.     ret
  785.  
  786. ;******************************************************
  787. ;
  788. ; void DIBconvert_32_to_16_dithered(
  789. ;    void *dest,        [ESP+ 4]
  790. ;    ulong dest_pitch,    [ESP+ 8]
  791. ;    void *src,        [ESP+12]
  792. ;    ulong src_pitch,    [ESP+16]
  793. ;    ulong width,        [ESP+20]
  794. ;    ulong height);        [ESP+24]
  795.  
  796. _DIBconvert_32_to_16_dithered:
  797.     test    _MMX_enabled,1
  798.     jnz    _DIBconvert_32_to_16_ditheredMMX
  799.     push    ebp
  800.     push    edi
  801.     push    esi
  802.     push    edx
  803.     push    ecx
  804.     push    ebx
  805.     push    eax
  806.  
  807.     push    0
  808.     push    0
  809.     push    0
  810.     push    0
  811.     push    0
  812.  
  813.     mov    esi,[esp+12+48]
  814.     mov    edi,[esp+4+48]
  815.  
  816.     mov    [esp+8],edi
  817.  
  818.     mov    ebp,[esp+20+48]
  819.     lea    eax,[ebp+ebp]
  820.     lea    ebx,[ebp*4]
  821.     sub    [esp+8+48],eax
  822.     sub    [esp+16+48],ebx
  823.  
  824.  
  825.     mov    edx,[esp+24+48]
  826. DIBconvert3216dithered@y:
  827.     mov    ebp,[esp+20+48]
  828.     push    ebp
  829.     push    edx
  830.     shr    ebp,1
  831.     jz    DIBconvert3216dithered@x2
  832.  
  833.     neg    ebp
  834.     shl    ebp,2
  835.     sub    [esp+16],ebp
  836.     sub    esi,ebp
  837.     sub    esi,ebp
  838.  
  839.     ;0 8 2 A
  840.     ;C 4 E 6
  841.     ;3 B 1 9
  842.     ;F 7 D 5
  843.  
  844.     ;Dithering algorithm:
  845.     ;    Multiply pixel by 249 to get an 5:11 fraction
  846.     ;    Add dithering value from above matrix as 0:11 fraction
  847.     ;
  848.     ;    (Use x241 for double dithering)
  849.  
  850. DIBconvert3216dithered@x:
  851.     mov    ecx,[esi+ebp*2+4]
  852.     mov    edx,0000ff00h
  853.  
  854.     and    edx,ecx
  855.     and    ecx,00ff00ffh
  856.  
  857.     mov    eax,ecx
  858.     mov    ebx,edx
  859.  
  860.     lea    ecx,[ecx*8]
  861.     lea    edx,[edx*8]
  862.  
  863.     sub    ecx,eax
  864.     sub    edx,ebx
  865.  
  866.     shl    eax,8
  867.     shl    ebx,8
  868.  
  869.     sub    eax,ecx
  870.     sub    ebx,edx
  871.  
  872.     mov    ecx,[esp+8]
  873.     mov    edx,[esp+12]
  874.  
  875.     xor    ecx,04000400h
  876.     xor    edx,00040000h
  877.  
  878.     add    eax,ecx
  879.     add    ebx,edx
  880.  
  881.     shr    ebx,14
  882.     mov    ecx,eax
  883.  
  884.     shr    eax,17
  885.     and    ecx,0000f800h
  886.  
  887.     shr    ecx,11
  888.     and    eax,00007c00h
  889.  
  890.     and    ebx,000003e0h
  891.     or    eax,ecx
  892.  
  893.     or    eax,ebx            ;combine pixel 2
  894.     mov    ecx,[esi+ebp*2]
  895.  
  896.     shl    eax,16
  897.     mov    edx,ecx
  898.  
  899.     and    ecx,00ff00ffh
  900.     and    edx,0000ff00h
  901.  
  902.     mov    edi,ecx
  903.     mov    ebx,edx
  904.  
  905.     lea    ecx,[ecx*8]
  906.     lea    edx,[edx*8]
  907.  
  908.     sub    ecx,edi
  909.     sub    edx,ebx
  910.  
  911.     shl    edi,8
  912.     shl    ebx,8
  913.  
  914.     sub    edi,ecx
  915.     sub    ebx,edx
  916.  
  917.     add    edi,[esp+8]
  918.     add    ebx,[esp+12]
  919.  
  920.     shr    ebx,14
  921.     mov    ecx,edi
  922.  
  923.     shr    edi,17
  924.     and    ecx,0000f800h
  925.  
  926.     shr    ecx,11
  927.     and    edi,00007c00h
  928.  
  929.     and    ebx,000003e0h
  930.     or    eax,edi
  931.  
  932.     or    eax,ebx
  933.     mov    edi,[esp+16]
  934.  
  935.     or    eax,ecx
  936.     mov    ecx,[esp+8]
  937.  
  938.     mov    [edi+ebp],eax
  939.     mov    edx,[esp+12]
  940.  
  941.     xor    ecx,01000100h
  942.     xor    edx,00010000h
  943.     mov    [esp+8],ecx
  944.     mov    [esp+12],edx
  945.  
  946.     add    ebp,4
  947.     jne    DIBconvert3216dithered@x
  948. DIBconvert3216dithered@x2:
  949.     pop    edx
  950.     pop    ebp
  951.     and    ebp,1
  952.     jz    DIBconvert3216dithered@x3
  953.     mov    eax,[esi]
  954.     add    esi,4
  955.  
  956.     mov    ebx,eax
  957.     mov    ecx,eax
  958.     shr    ebx,3
  959.     and    ecx,0000f800h
  960.     shr    eax,9
  961.     and    ebx,0000001fh
  962.     shr    ecx,6
  963.     and    eax,00007c00h
  964.     or    ebx,ecx
  965.     or    ebx,eax
  966.     mov    [edi+0],bl
  967.     mov    [edi+1],bh
  968.     add    edi,2
  969. DIBconvert3216dithered@x3:
  970.  
  971.     add    esi,[esp+16+48]
  972.     add    edi,[esp+ 8+48]
  973.  
  974.     mov    [esp+8],edi
  975.  
  976.     mov    eax,06000600h
  977.     mov    ebx,00060000h
  978.  
  979.     test    edx,1
  980.     jz    DIBconvert3216dithered@even
  981.  
  982.     mov    eax,07800780h
  983.     mov    ebx,00078000h
  984.  
  985. DIBconvert3216dithered@even:
  986.  
  987.     xor    eax,[esp+12]
  988.     xor    ebx,[esp+16]
  989.     mov    [esp+12],eax
  990.     mov    [esp+16],ebx
  991.     mov    [esp+0],eax
  992.     mov    [esp+4],ebx
  993.  
  994.     dec    edx
  995.     jne    DIBconvert3216dithered@y
  996.  
  997.     pop    eax
  998.     pop    eax
  999.     pop    eax
  1000.     pop    eax
  1001.     pop    eax
  1002.  
  1003.     pop    eax
  1004.     pop    ebx
  1005.     pop    ecx
  1006.     pop    edx
  1007.     pop    esi
  1008.     pop    edi
  1009.     pop    ebp
  1010.  
  1011.     ret
  1012.  
  1013. ;******************************************************
  1014.  
  1015.     .const
  1016.  
  1017.     align    8
  1018. DIBconvert3216ditheredMMX@mult            dq    00f100f100f100f1h
  1019. DIBconvert3216ditheredMMX@horizstep1mask    dq    0400040004000400h
  1020. DIBconvert3216ditheredMMX@horizstep2mask    dq    0100010001000100h
  1021. DIBconvert3216ditheredMMX@vertstep1mask        dq    0600060006000600h
  1022. DIBconvert3216ditheredMMX@vertstep2mask        dq    0780078007800780h
  1023. DIBconvert3216ditheredMMX@mult565        dq    00f100f100f900f1h
  1024. DIBconvert3216ditheredMMX@565horizstep1mask    dq    0400040002000400h
  1025. DIBconvert3216ditheredMMX@565horizstep2mask    dq    0100010000800100h
  1026. DIBconvert3216ditheredMMX@565vertstep1mask    dq    0600060003000600h
  1027. DIBconvert3216ditheredMMX@565vertstep2mask    dq    0780078003c00780h
  1028.  
  1029.     .code
  1030.  
  1031.     align    16
  1032. _DIBconvert_32_to_16_ditheredMMX:
  1033.     push    ebp
  1034.     push    edi
  1035.     push    esi
  1036.     push    edx
  1037.     push    ecx
  1038.     push    ebx
  1039.     push    eax
  1040.  
  1041.     push    0
  1042.     push    0
  1043.     push    0
  1044.     push    0
  1045.  
  1046.     mov    esi,[esp+12+44]
  1047.     mov    edi,[esp+4+44]
  1048.  
  1049.     mov    ebp,[esp+20+44]
  1050.     lea    eax,[ebp+ebp]
  1051.     lea    ebx,[ebp*4]
  1052.     sub    [esp+8+44],eax
  1053.     sub    [esp+16+44],ebx
  1054.  
  1055.     movq    mm6,DIBconvert3216ditheredMMX@mult
  1056.     pxor    mm7,mm7
  1057.     movq    mm5,DIBconvert3216ditheredMMX@horizstep1mask
  1058.     pxor    mm4,mm4
  1059.  
  1060.  
  1061.     mov    edx,[esp+24+44]
  1062. DIBconvert3216ditheredMMX@y:
  1063.     mov    ebp,[esp+20+44]
  1064.     shr    ebp,2
  1065.     jz    DIBconvert3216ditheredMMX@x2
  1066.  
  1067.     neg    ebp
  1068.     shl    ebp,3
  1069.     sub    edi,ebp
  1070.     sub    esi,ebp
  1071.     sub    esi,ebp
  1072.  
  1073.     movq    [esp+0],mm4
  1074.     movq    [esp+8],mm5
  1075.  
  1076.     ;0 8 2 A
  1077.     ;C 4 E 6
  1078.     ;3 B 1 9
  1079.     ;F 7 D 5
  1080.  
  1081.     ;Dithering algorithm:
  1082.     ;    Multiply pixel by 249 to get an 5:11 fraction
  1083.     ;    Add dithering value from above matrix as 0:11 fraction
  1084.     ;
  1085.     ;    (Use x241 for double dithering)
  1086.     ;
  1087.     ;    mm6: 241,241,241,241
  1088.     ;    mm7: zero
  1089.  
  1090. DIBconvert3216ditheredMMX@x:
  1091.  
  1092.     movq    mm0,[esi+ebp*2]
  1093.  
  1094.     movq    mm2,[esi+ebp*2+8]
  1095.     movq    mm1,mm0
  1096.  
  1097.     punpcklbw mm0,mm7
  1098.     movq    mm3,mm2
  1099.  
  1100.     pmullw    mm0,mm6
  1101.     punpckhbw mm1,mm7
  1102.  
  1103.     pmullw    mm1,mm6
  1104.     punpcklbw mm2,mm7
  1105.  
  1106.     pmullw    mm2,mm6
  1107.     punpckhbw mm3,mm7
  1108.  
  1109.     pmullw    mm3,mm6
  1110.     paddw    mm0,mm4
  1111.  
  1112.     psrlw    mm0,8
  1113.     paddw    mm1,mm5
  1114.  
  1115.     psrlw    mm1,8
  1116.     paddw    mm2,mm4
  1117.  
  1118.     psrlw    mm2,8
  1119.     paddw    mm3,mm5
  1120.  
  1121.     psrlw    mm3,8
  1122.     packuswb mm0,mm1
  1123.  
  1124.     packuswb mm2,mm3
  1125.     movq    mm1,mm0
  1126.  
  1127.     pand    mm0,DIBconvert3216MMX@red_blue_mask
  1128.     movq    mm3,mm2
  1129.  
  1130.     pmaddwd mm0,DIBconvert3216MMX@red_blue_mult
  1131.  
  1132.     pand    mm2,DIBconvert3216MMX@red_blue_mask
  1133.  
  1134.     pmaddwd mm2,DIBconvert3216MMX@red_blue_mult
  1135.  
  1136.     pand    mm1,DIBconvert3216MMX@green_mask
  1137.     add    ebp,8
  1138.  
  1139.     pand    mm3,DIBconvert3216MMX@green_mask
  1140.     por    mm0,mm1
  1141.  
  1142.     por    mm2,mm3
  1143.     psrld    mm0,6
  1144.  
  1145.     pxor    mm4,DIBconvert3216ditheredMMX@horizstep2mask
  1146.     psrld    mm2,6
  1147.  
  1148.     pxor    mm5,DIBconvert3216ditheredMMX@horizstep2mask
  1149.     packssdw mm0,mm2
  1150.  
  1151.     movq    [edi+ebp-8],mm0
  1152.     jne    DIBconvert3216ditheredMMX@x
  1153. DIBconvert3216ditheredMMX@x2:
  1154.     mov    ebp,[esp+20+44]
  1155.     and    ebp,3
  1156.     jz    DIBconvert3216ditheredMMX@x3
  1157. DIBconvert3216ditheredMMX@xleftover:
  1158.     mov    eax,[esi]
  1159.     add    esi,4
  1160.  
  1161.     mov    ebx,eax
  1162.     mov    ecx,eax
  1163.     shr    ebx,3
  1164.     and    ecx,0000f800h
  1165.     shr    eax,9
  1166.     and    ebx,0000001fh
  1167.     shr    ecx,6
  1168.     and    eax,00007c00h
  1169.     or    ebx,ecx
  1170.     or    ebx,eax
  1171.     mov    [edi+0],bl
  1172.     mov    [edi+1],bh
  1173.     add    edi,2
  1174.  
  1175.     dec    ebp
  1176.     jne    DIBconvert3216ditheredMMX@xleftover
  1177. DIBconvert3216ditheredMMX@x3:
  1178.  
  1179.     add    esi,[esp+16+44]
  1180.     add    edi,[esp+ 8+44]
  1181.  
  1182.     movq    mm4,[esp+0]
  1183.     movq    mm5,[esp+8]
  1184.  
  1185.     movq    mm0,DIBconvert3216ditheredMMX@vertstep1mask
  1186.  
  1187.     test    edx,1
  1188.     jz    DIBconvert3216ditheredMMX@even
  1189.  
  1190.     movq    mm0,DIBconvert3216ditheredMMX@vertstep2mask
  1191.  
  1192. DIBconvert3216ditheredMMX@even:
  1193.  
  1194.     pxor    mm4,mm0
  1195.     pxor    mm5,mm0
  1196.  
  1197.     dec    edx
  1198.     jne    DIBconvert3216ditheredMMX@y
  1199.  
  1200.     pop    eax
  1201.     pop    eax
  1202.     pop    eax
  1203.     pop    eax
  1204.  
  1205.     pop    eax
  1206.     pop    ebx
  1207.     pop    ecx
  1208.     pop    edx
  1209.     pop    esi
  1210.     pop    edi
  1211.     pop    ebp
  1212.  
  1213.     emms
  1214.     ret
  1215.  
  1216. ;******************************************************
  1217.  
  1218. ;******************************************************
  1219. ;
  1220. ; void DIBconvert_32_to_16_565_dithered(
  1221. ;    void *dest,        [ESP+ 4]
  1222. ;    ulong dest_pitch,    [ESP+ 8]
  1223. ;    void *src,        [ESP+12]
  1224. ;    ulong src_pitch,    [ESP+16]
  1225. ;    ulong width,        [ESP+20]
  1226. ;    ulong height);        [ESP+24]
  1227.  
  1228. _DIBconvert_32_to_16_565_dithered:
  1229.     test    _MMX_enabled,1
  1230.     jnz    _DIBconvert_32_to_16_565_ditheredMMX
  1231.     push    ebp
  1232.     push    edi
  1233.     push    esi
  1234.     push    edx
  1235.     push    ecx
  1236.     push    ebx
  1237.     push    eax
  1238.  
  1239.     push    0
  1240.     push    0
  1241.     push    0
  1242.     push    0
  1243.     push    0
  1244.  
  1245.     mov    esi,[esp+12+48]
  1246.     mov    edi,[esp+4+48]
  1247.  
  1248.     mov    [esp+8],edi
  1249.  
  1250.     mov    ebp,[esp+20+48]
  1251.     lea    eax,[ebp+ebp]
  1252.     lea    ebx,[ebp*4]
  1253.     sub    [esp+8+48],eax
  1254.     sub    [esp+16+48],ebx
  1255.  
  1256.  
  1257.     mov    edx,[esp+24+48]
  1258. DIBconvert3216565dithered@y:
  1259.     mov    ebp,[esp+20+48]
  1260.     push    ebp
  1261.     push    edx
  1262.     shr    ebp,1
  1263.     jz    DIBconvert3216565dithered@x2
  1264.  
  1265.     neg    ebp
  1266.     shl    ebp,2
  1267.     sub    [esp+16],ebp
  1268.     sub    esi,ebp
  1269.     sub    esi,ebp
  1270.  
  1271.     ;0 8 2 A
  1272.     ;C 4 E 6
  1273.     ;3 B 1 9
  1274.     ;F 7 D 5
  1275.  
  1276.     ;Dithering algorithm:
  1277.     ;    Multiply pixel by 249 to get an 5:11 fraction
  1278.     ;    Add dithering value from above matrix as 0:11 fraction
  1279.     ;
  1280.     ;    (Use x241 for double dithering)
  1281.  
  1282. DIBconvert3216565dithered@x:
  1283.     mov    ecx,[esi+ebp*2+4]
  1284.     mov    edx,0000ff00h
  1285.  
  1286.     and    edx,ecx
  1287.     and    ecx,00ff00ffh
  1288.  
  1289.     mov    eax,ecx
  1290.     mov    ebx,edx
  1291.  
  1292.     lea    ecx,[ecx*8]
  1293.     lea    edx,[edx*8]
  1294.  
  1295.     sub    ecx,eax
  1296.     sub    edx,ebx
  1297.  
  1298.     shl    eax,8
  1299.     shl    ebx,8
  1300.  
  1301.     sub    eax,ecx
  1302.     sub    ebx,edx
  1303.  
  1304.     mov    ecx,[esp+8]
  1305.     mov    edx,[esp+12]
  1306.  
  1307.     xor    ecx,04000400h
  1308.     xor    edx,00040000h
  1309.  
  1310.     add    eax,ecx
  1311.     add    ebx,edx
  1312.  
  1313.     shr    ebx,13
  1314.     mov    ecx,eax
  1315.  
  1316.     shr    eax,16
  1317.     and    ecx,0000f800h
  1318.  
  1319.     shr    ecx,11
  1320.     and    eax,0000f800h
  1321.  
  1322.     and    ebx,000007e0h
  1323.     or    eax,ecx
  1324.  
  1325.     or    eax,ebx            ;combine pixel 2
  1326.     mov    ecx,[esi+ebp*2]
  1327.  
  1328.     shl    eax,16
  1329.     mov    edx,ecx
  1330.  
  1331.     and    ecx,00ff00ffh
  1332.     and    edx,0000ff00h
  1333.  
  1334.     mov    edi,ecx
  1335.     mov    ebx,edx
  1336.  
  1337.     lea    ecx,[ecx*8]
  1338.     lea    edx,[edx*8]
  1339.  
  1340.     sub    ecx,edi
  1341.     sub    edx,ebx
  1342.  
  1343.     shl    edi,8
  1344.     shl    ebx,8
  1345.  
  1346.     sub    edi,ecx
  1347.     sub    ebx,edx
  1348.  
  1349.     add    edi,[esp+8]
  1350.     add    ebx,[esp+12]
  1351.  
  1352.     shr    ebx,13
  1353.     mov    ecx,edi
  1354.  
  1355.     shr    edi,16
  1356.     and    ecx,0000f800h
  1357.  
  1358.     shr    ecx,11
  1359.     and    edi,0000f800h
  1360.  
  1361.     and    ebx,000007e0h
  1362.     or    eax,edi
  1363.  
  1364.     or    eax,ebx
  1365.     mov    edi,[esp+16]
  1366.  
  1367.     or    eax,ecx
  1368.     mov    ecx,[esp+8]
  1369.  
  1370.     mov    [edi+ebp],eax
  1371.     mov    edx,[esp+12]
  1372.  
  1373.     xor    ecx,01000100h
  1374.     xor    edx,00010000h
  1375.     mov    [esp+8],ecx
  1376.     mov    [esp+12],edx
  1377.  
  1378.     add    ebp,4
  1379.     jne    DIBconvert3216565dithered@x
  1380. DIBconvert3216565dithered@x2:
  1381.     pop    edx
  1382.     pop    ebp
  1383.     and    ebp,1
  1384.     jz    DIBconvert3216565dithered@x3
  1385.     mov    eax,[esi]
  1386.     add    esi,4
  1387.  
  1388.     mov    ebx,eax
  1389.     mov    ecx,eax
  1390.     shr    ebx,3
  1391.     and    ecx,0000f800h
  1392.     shr    eax,8
  1393.     and    ebx,0000001fh
  1394.     shr    ecx,5
  1395.     and    eax,0000fc00h
  1396.     or    ebx,ecx
  1397.     or    ebx,eax
  1398.     mov    [edi+0],bl
  1399.     mov    [edi+1],bh
  1400.     add    edi,2
  1401. DIBconvert3216565dithered@x3:
  1402.  
  1403.     add    esi,[esp+16+48]
  1404.     add    edi,[esp+ 8+48]
  1405.  
  1406.     mov    [esp+8],edi
  1407.  
  1408.     mov    eax,06000600h
  1409.     mov    ebx,00060000h
  1410.  
  1411.     test    edx,1
  1412.     jz    DIBconvert3216565dithered@even
  1413.  
  1414.     mov    eax,07800780h
  1415.     mov    ebx,00078000h
  1416.  
  1417. DIBconvert3216565dithered@even:
  1418.  
  1419.     xor    eax,[esp+12]
  1420.     xor    ebx,[esp+16]
  1421.     mov    [esp+12],eax
  1422.     mov    [esp+16],ebx
  1423.     mov    [esp+0],eax
  1424.     mov    [esp+4],ebx
  1425.  
  1426.     dec    edx
  1427.     jne    DIBconvert3216565dithered@y
  1428.  
  1429.     pop    eax
  1430.     pop    eax
  1431.     pop    eax
  1432.     pop    eax
  1433.     pop    eax
  1434.  
  1435.     pop    eax
  1436.     pop    ebx
  1437.     pop    ecx
  1438.     pop    edx
  1439.     pop    esi
  1440.     pop    edi
  1441.     pop    ebp
  1442.  
  1443.     ret
  1444.  
  1445. ;******************************************************
  1446.  
  1447.     align    8
  1448.  
  1449. _DIBconvert_32_to_16_565_ditheredMMX:
  1450.     push    ebp
  1451.     push    edi
  1452.     push    esi
  1453.     push    edx
  1454.     push    ecx
  1455.     push    ebx
  1456.     push    eax
  1457.  
  1458.     push    0
  1459.     push    0
  1460.     push    0
  1461.     push    0
  1462.  
  1463.     mov    esi,[esp+12+44]
  1464.     mov    edi,[esp+4+44]
  1465.  
  1466.     mov    ebp,[esp+20+44]
  1467.     lea    eax,[ebp+ebp]
  1468.     lea    ebx,[ebp*4]
  1469.     sub    [esp+8+44],eax
  1470.     sub    [esp+16+44],ebx
  1471.  
  1472.     movq    mm6,DIBconvert3216ditheredMMX@mult565
  1473.     pxor    mm7,mm7
  1474.     movq    mm5,DIBconvert3216ditheredMMX@565horizstep1mask
  1475.     pxor    mm4,mm4
  1476.  
  1477.  
  1478.     mov    edx,[esp+24+44]
  1479. DIBconvert3216565ditheredMMX@y:
  1480.     mov    ebp,[esp+20+44]
  1481.     shr    ebp,2
  1482.     jz    DIBconvert3216565ditheredMMX@x2
  1483.  
  1484.     neg    ebp
  1485.     shl    ebp,3
  1486.     sub    edi,ebp
  1487.     sub    esi,ebp
  1488.     sub    esi,ebp
  1489.  
  1490.     movq    [esp+0],mm4
  1491.     movq    [esp+8],mm5
  1492.  
  1493.     ;0 8 2 A
  1494.     ;C 4 E 6
  1495.     ;3 B 1 9
  1496.     ;F 7 D 5
  1497.  
  1498.     ;Dithering algorithm:
  1499.     ;    Multiply pixel by 249 to get an 5:11 fraction
  1500.     ;    Add dithering value from above matrix as 0:11 fraction
  1501.     ;
  1502.     ;    (Use x241 for double dithering)
  1503.     ;
  1504.     ;    mm6: 241,241,249,241
  1505.     ;    mm7: zero
  1506.  
  1507. DIBconvert3216565ditheredMMX@x:
  1508.  
  1509.     movq    mm0,[esi+ebp*2]
  1510.  
  1511.     movq    mm2,[esi+ebp*2+8]
  1512.     movq    mm1,mm0
  1513.  
  1514.     punpcklbw mm0,mm7
  1515.     movq    mm3,mm2
  1516.  
  1517.     pmullw    mm0,mm6
  1518.     punpckhbw mm1,mm7
  1519.  
  1520.     pmullw    mm1,mm6
  1521.     punpcklbw mm2,mm7
  1522.  
  1523.     pmullw    mm2,mm6
  1524.     punpckhbw mm3,mm7
  1525.  
  1526.     pmullw    mm3,mm6
  1527.     paddw    mm0,mm4
  1528.  
  1529.     psrlw    mm0,8
  1530.     paddw    mm1,mm5
  1531.  
  1532.     psrlw    mm1,8
  1533.     paddw    mm2,mm4
  1534.  
  1535.     psrlw    mm2,8
  1536.     paddw    mm3,mm5
  1537.  
  1538.     psrlw    mm3,8
  1539.     packuswb mm0,mm1
  1540.  
  1541.     packuswb mm2,mm3
  1542.     movq    mm1,mm0
  1543.  
  1544.     pand    mm0,DIBconvert3216MMX@red_blue_mask
  1545.     movq    mm3,mm2
  1546.  
  1547.     pmaddwd mm0,DIBconvert3216MMX@565_red_blue_mult
  1548.  
  1549.     pand    mm2,DIBconvert3216MMX@red_blue_mask
  1550.  
  1551.     pmaddwd mm2,DIBconvert3216MMX@565_red_blue_mult
  1552.  
  1553.     pand    mm1,DIBconvert3216MMX@565_green_mask
  1554.     add    ebp,8
  1555.  
  1556.     pand    mm3,DIBconvert3216MMX@565_green_mask
  1557.     por    mm0,mm1
  1558.  
  1559.     por    mm2,mm3
  1560.     pslld    mm0,16-5
  1561.  
  1562.     pxor    mm4,DIBconvert3216ditheredMMX@565horizstep2mask
  1563.     pslld    mm2,16-5
  1564.  
  1565.     psrad    mm0,16
  1566.     psrad    mm2,16
  1567.  
  1568.     pxor    mm5,DIBconvert3216ditheredMMX@565horizstep2mask
  1569.     packssdw mm0,mm2
  1570.  
  1571.     movq    [edi+ebp-8],mm0
  1572.     jne    DIBconvert3216565ditheredMMX@x
  1573. DIBconvert3216565ditheredMMX@x2:
  1574.     mov    ebp,[esp+20+44]
  1575.     and    ebp,3
  1576.     jz    DIBconvert3216565ditheredMMX@x3
  1577. DIBconvert3216565ditheredMMX@xleftover:
  1578.     mov    eax,[esi]
  1579.     add    esi,4
  1580.  
  1581.     mov    ebx,eax
  1582.     mov    ecx,eax
  1583.     shr    ebx,3
  1584.     and    ecx,0000fe00h
  1585.     shr    eax,8
  1586.     and    ebx,0000001fh
  1587.     shr    ecx,5
  1588.     and    eax,0000f800h
  1589.     or    ebx,ecx
  1590.     or    ebx,eax
  1591.     mov    [edi+0],bl
  1592.     mov    [edi+1],bh
  1593.     add    edi,2
  1594.  
  1595.     dec    ebp
  1596.     jne    DIBconvert3216565ditheredMMX@xleftover
  1597. DIBconvert3216565ditheredMMX@x3:
  1598.  
  1599.     add    esi,[esp+16+44]
  1600.     add    edi,[esp+ 8+44]
  1601.  
  1602.     movq    mm4,[esp+0]
  1603.     movq    mm5,[esp+8]
  1604.  
  1605.     movq    mm0,DIBconvert3216ditheredMMX@565vertstep1mask
  1606.  
  1607.     test    edx,1
  1608.     jz    DIBconvert3216565ditheredMMX@even
  1609.  
  1610.     movq    mm0,DIBconvert3216ditheredMMX@565vertstep2mask
  1611.  
  1612. DIBconvert3216565ditheredMMX@even:
  1613.  
  1614.     pxor    mm4,mm0
  1615.     pxor    mm5,mm0
  1616.  
  1617.     dec    edx
  1618.     jne    DIBconvert3216565ditheredMMX@y
  1619.  
  1620.     pop    eax
  1621.     pop    eax
  1622.     pop    eax
  1623.     pop    eax
  1624.  
  1625.     pop    eax
  1626.     pop    ebx
  1627.     pop    ecx
  1628.     pop    edx
  1629.     pop    esi
  1630.     pop    edi
  1631.     pop    ebp
  1632.  
  1633.     emms
  1634.     ret
  1635.  
  1636. ;******************************************************
  1637.  
  1638.     end
  1639.